package cn.john.hrm.service.impl;

import cn.john.hrm.constant.RegistConstant;
import cn.john.hrm.domain.VipUser;
import cn.john.hrm.dto.SmsDto;
import cn.john.hrm.mapper.VipUserMapper;
import cn.john.hrm.service.IVerifyCodeService;
import cn.john.hrm.util.AjaxResult;
import cn.john.hrm.util.ValidUtils;
import cn.john.hrm.util.VerifyCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private VipUserMapper vipUserMapper;

    @Override
    public AjaxResult imageCode(String key) throws IOException {
        // 校验Key是否为空
        ValidUtils.assertNotNull(key, "获取验证码失败，请重试");
        // 将验证码转换为base64格式
        BASE64Encoder encoder = new BASE64Encoder();
        String code = VerifyCodeUtils.generateVerifyCode(4).toLowerCase();
        // 将code存入Redis
        redisTemplate.opsForValue().set(key, code,3L, TimeUnit.MINUTES);
        ByteArrayOutputStream data = new ByteArrayOutputStream();
        VerifyCodeUtils.outputImage(100, 40, data,code);
        String encode = encoder.encode(data.toByteArray());
        return AjaxResult.me().setResultObj(encode);
    }

    @Override
    public AjaxResult sendSmsCode(@Valid SmsDto smsDto) {
        // 校验参数交给jsr303
        VipUser vipUser = new VipUser();
        vipUser.setPhone(smsDto.getMobile());
        // 校验手机号是否已经注册
        VipUser user = vipUserMapper.selectOne(vipUser);
        // 如果user不为空，则是已经注册过
        if (user != null)
            throw new RuntimeException("该手机号已经注册!");
        // 如果没有注册，则通过redis中的图片验证码和用户输入的验证码进行比较
        String codeKey = smsDto.getImageCodeKey();
        Object obj = redisTemplate.opsForValue().get(codeKey);
        ValidUtils.assertNotNull(obj, "图片已失效");
        String imgCode = obj.toString();
        // 获取用户输入的验证码并转换成小写
        String userImgCode = smsDto.getImageCode().toLowerCase().trim();
        if (!userImgCode.equals(imgCode))
            throw new RuntimeException("验证码输入错误,请重新输入!");
        // 校验成功通过调用第三方短信接口给用户发送验证码短信,并将验证码存储到redis中
        // 定义验证码
        String phoneCode = VerifyCodeUtils.generateVerifyCode(6, "1234567890");
        // 发送验证码给用户
        System.out.println("您的验证码是: " + phoneCode + " ,请在5分钟内使用!");
        // 将验证码存到redis中
        String key = RegistConstant.REGIST_KEY + "::" + smsDto.getMobile() ;
        redisTemplate.opsForValue().set(key, phoneCode,3L,TimeUnit.MINUTES);
        return AjaxResult.me();
    }
}
